﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using WXDba.Entity;
using WXDba.Abstract;
using System.Data.Entity;

namespace WXDba.Factory
{
    /// <summary>
    /// 微信用户操作，封装
    /// </summary>
    internal class WXUserOperate : BaseOperate, IWXUser
    {
        #region 基础访问  
        /// <summary>  
        /// 获取表达式树  
        /// </summary>  
        /// <returns></returns>  
        public DbSet<WXUser> GetDbSet()
        {
            return Context.WXUsers;
        }
        /// <summary>  
        /// 获取对象  
        /// </summary>  
        /// <param name="ID">主键ID</param>  
        /// <returns></returns>  
        public WXUser GetModel(int ID)
        {
            return GetDbSet().Find(ID);
        }
        /// <summary>  
        /// 添加对象  
        /// </summary>  
        /// <param name="model">对象</param>  
        /// <returns></returns>  
        public bool Add(WXUser model)
        {
            if (IsValided(model) == false)
                return false;
            try
            {
                GetDbSet().Add(model);
                return Save() > 0;
            }
            catch (Exception ex)
            {
                return Error_Add(ex);
            }
        }
        /// <summary>  
        /// 修改对象  
        /// </summary>  
        /// <param name="model">对象</param>  
        /// <returns></returns>  
        public bool Modify(WXUser model)
        {
            if (IsValided(model) == false)
                return false;
            try
            {
                return SetModify(model);
            }
            catch (Exception ex)
            {
                return Error_Modify(ex);
            }
        }
        /// <summary>  
        /// 删除对象  
        /// </summary>  
        /// <param name="model">对象</param>  
        /// <returns></returns>  
        public bool Delete(WXUser model)
        {
            try
            {
                GetDbSet().Remove(model);
                return Save() > 0;
            }
            catch (Exception ex)
            {
                return Error_Delete(ex);
            }
        }
        /// <summary>  
        /// 删除对象  
        /// </summary>  
        /// <param name="ID">主键ID</param>  
        /// <returns></returns>  
        public bool Delete(int ID)
        {
            WXUser model = GetModel(ID);
            if (model == null)
                throw new Exception(string.Format("删除对象时，获取ID={0}的对象失败", ID));
            return Delete(model);
        }
        #endregion

        #region 获取对象
        /// <summary>
        /// 盘点openid，是否已经存在
        /// </summary>
        /// <param name="OpenID">当前用户的OPENID</param>
        /// <returns></returns>
        public bool IsExists_OpenID(string OpenID)
        {
            return GetDbSet().Any(q => q.OpenID == OpenID);
        }
        /// <summary>
        /// 判断UnionID，是否已经存在
        /// </summary>
        /// <param name="UnionID"></param>
        /// <returns></returns>
        public bool IsExists_UnionID(string UnionID)
        {
            return GetDbSet().Any(q => q.UnionID == UnionID);
        }
        /// <summary>
        /// 获取OpenID对象的用户对象
        /// </summary>
        /// <param name="OpenID">当前OpenID</param>
        /// <returns></returns>
        public WXUser GetModel_OpenID(string OpenID)
        {
            return GetDbSet().Where(q => q.OpenID == OpenID).FirstOrDefault();
        }
        /// <summary>
        /// 获取UnionID对应的用户对象
        /// </summary>
        /// <param name="UnionID"></param>
        /// <returns></returns>
        public WXUser GetModel_UnionID(string UnionID)
        {
            return GetDbSet().Where(q => q.UnionID == UnionID).FirstOrDefault();
        }
        #endregion

        #region 扩展接口
        /// <summary>
        /// 批量添加 微信用户列表的OpenID
        /// </summary>
        /// <param name="OpenIDList"></param>
        public bool AddOpenIDList(List<string> OpenIDList)
        {
            foreach (var item in OpenIDList)
            {
                if (string.IsNullOrEmpty(item) == false && IsExists_OpenID(item) == false)
                {
                    WXUser model = new WXUser();
                    model.OpenID = item;
                    model.AddTime = DateTime.Now;
                    GetDbSet().Add(model);
                }
            }
            return Save() > 0;
        }
        /// <summary>
        /// 添加或修改对象
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool AddOrUpdate(WXUser model)
        {
            //判断是否存在
            if (IsExists_OpenID(model.OpenID))
            {
                return Update(model);
            }
            else
            {
                model.AddTime = DateTime.Now;
                return Add(model);
            }
        }
        /// <summary>
        /// 添加或修改对象（授权用户信息）
        /// </summary>
        /// <param name="oauth">授权用户信息</param>
        /// <returns></returns>
        public WXUser AddOrUpdate(OAuthUser oauth)
        {
            //判断是否存在
            if (IsExists_OpenID(oauth.openid))
            {
                //修改
                WXUser model =GetModel_OpenID(oauth.openid);
                model.NickName = oauth.nickname;
                model.Sex = oauth.sex;
                model.Province = oauth.province;
                model.City = oauth.city;
                model.County = oauth.country;
                model.HeadImgUrl = oauth.headimgurl;
                model.UnionID = oauth.unionid;
                model.UpdateTime = DateTime.Now;

                Save();
                return model;
            }
            else
            {
                //添加
                WXUser model = new WXUser();
                model.OpenID = oauth.openid;
                model.NickName = oauth.nickname;
                model.Sex = oauth.sex;
                model.Province = oauth.province;
                model.City = oauth.city;
                model.County = oauth.country;
                model.HeadImgUrl = oauth.headimgurl;
                model.OpenID = oauth.openid;
                model.AddTime = DateTime.Now;
                //添加到数据库
                Add(model);
                return model;
            }
        }
        /// <summary>
        /// 根据OpenID，同步用户对象
        /// </summary>
        /// <param name="newModel">新对象</param>
        /// <returns></returns>
        public bool Update(WXUser newModel)
        {
            WXUser model = GetModel_OpenID(newModel.OpenID);
            if (model == null)
                return false;
            model.Subscribe = newModel.Subscribe;
            model.NickName = newModel.NickName;

            model.Sex = newModel.Sex;
            model.County = newModel.County;
            model.Province = newModel.Province;
            model.City = newModel.City;
            model.Language = newModel.Language;
            model.HeadImgUrl = newModel.HeadImgUrl;
            model.Subcribe_Time = newModel.Subcribe_Time;
            model.UnionID = newModel.UnionID;
            model.Remark = newModel.Remark;
            model.GroupID = newModel.GroupID;
            model.UpdateTime = DateTime.Now;
            return Save() > 0;
        }
        /// <summary>
        /// 修改用户的备注
        /// </summary>
        /// <param name="OpenID">OpenID</param>
        /// <param name="Remarik">备注内容</param>
        /// <returns></returns>
        public bool UpdateRemark(string OpenID, string Remarik)
        {
            WXUser user = GetModel_OpenID(OpenID);
            if (user == null)
                return false;
            user.Remark = Remarik;
            Save();
            return true;
        }
        /// <summary>
        /// 修改用户分组
        /// </summary>
        /// <param name="idList">OpenID</param>
        /// <param name="GroupID">用户分组ID</param>
        /// <returns></returns>
        public bool UpdateGroup(List<string> idList, int GroupID)
        {
            foreach (var item in idList)
            {
                WXUser model = GetModel_OpenID(item);
                if (model == null)
                    continue;
                model.GroupID = GroupID;
            }
            return Save() > 0;
        }
        #endregion

        #region 获取列表
        /// <summary>
        /// 获取用户分页列表
        /// </summary>
        /// <param name="info">分页信息</param>
        /// <param name="NickName">用户昵称</param>
        /// <returns></returns>
        public List<WXUser> GetPage(PageInfo info, string NickName = null, bool? Subscribe = null)
        {
            IQueryable<WXUser> query = GetDbSet();
            //昵称
            if (string.IsNullOrEmpty(NickName) == false)
                query = query.Where(q => q.NickName.Contains(NickName));
            //是否关注
            if (Subscribe != null)
                query = query.Where(q => q.Subscribe == Subscribe);
            query = query.OrderByDescending(q => q.AddTime);
            return query.Skip(info.SkipCount)
                .Take(info.PageSize)
                .ToList();
        }
        /// <summary>
        /// 遍历数据库所有的OpenID，100个位单位，每次遍历成功触发onPageSuccess
        /// </summary>
        /// <param name="onPageSuccess"></param>
        public void ForeachOpenID(Action<List<string>> onPageSuccess)
        {
            int pageSize = 100;
            int total = GetDbSet().Count();
            int pageCount = new PageInfo() { PageSize = pageSize, RecordCount = total }.PageCount;
            for (int i = 1; i <= pageCount; i++)
            {
                PageInfo info = new PageInfo(i, pageSize);
                List<WXUser> userList = GetPage(info);
                List<string> idList = userList.Select(q => q.OpenID).ToList();
                //获取列表成功
                if (onPageSuccess != null)
                    onPageSuccess(idList);
            }
        }
        #endregion

        #region 获取数量
        /// <summary>
        /// 获取关注的用户总量
        /// </summary>
        /// <returns></returns>
        public int GetCount()
        {
            return GetDbSet().Where(q => q.Subscribe == true).Count();
        }
        #endregion
    }
}
